package cn.zfs.springcloud.util.util;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 文件读取工具类
 */
public class FileUtil {

    /**
     * 读取文件内容，作为字符串返回
     */
    public static String readFileAsString(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException(filePath);
        }

        if (file.length() > 1024 * 1024 * 1024) {
            throw new IOException("File is too large");
        }

        StringBuilder sb = new StringBuilder((int) (file.length()));
        // 创建字节输入流  
        FileInputStream fis = new FileInputStream(filePath);
        // 创建一个长度为10240的Buffer
        byte[] bbuf = new byte[10240];
        // 用于保存实际读取的字节数  
        int hasRead = 0;
        while ((hasRead = fis.read(bbuf)) > 0) {
            sb.append(new String(bbuf, 0, hasRead));
        }
        fis.close();
        return sb.toString();
    }

    /**
     * 根据文件路径读取byte[] 数组
     */
    public static byte[] readFileToBytes(String filePath) throws IOException {
        File file = new File(filePath);
        return readFileToBytes(file);
    }

    /**
     * 根据文件路径读取byte[] 数组
     */
    public static byte[] readFileToBytes(File file) throws IOException {
        if (file == null || !file.exists()) {
            throw new FileNotFoundException();
        } else {
            return readFileToBytes(new FileInputStream(file));
        }
    }

    /**
     * 根据文件路径读取byte[] 数组
     */
    public static byte[] readFileToBytes(InputStream inputStream) throws IOException {
        if (inputStream == null) {
            throw new FileNotFoundException();
        } else {
            try (BufferedInputStream in = new BufferedInputStream(inputStream);
                 ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
                short bufSize = 1024;
                byte[] buffer = new byte[bufSize];
                int len;
                while (-1 != (len = in.read(buffer, 0, bufSize))) {
                    bos.write(buffer, 0, len);
                }
                return bos.toByteArray();
            }
        }
    }

    /**
     * 使用随机流读取文件
     *
     * @param filePath 文件路径
     * @param pos      开始位置 一个汉字等于3
     * @return
     */
    public static Map<String, Object> randomAccessFile(String filePath, long pos) {
        Map<String, Object> resultMap = new HashMap<>();
        try (RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "rw")) {
            StringBuilder resultStr = new StringBuilder();
            resultMap.put("fileLength", randomAccessFile.length());
            randomAccessFile.seek(pos);
            String readLine = randomAccessFile.readLine();
            while (StringUtils.isNotBlank(readLine)) {
                resultStr.append(readLine);
                readLine = randomAccessFile.readLine();
            }
            readLine = new String(resultStr.toString().getBytes("ISO-8859-1"), "utf-8");
            resultMap.put("fileContent", readLine);
        } catch (Exception e) {
            resultMap.put("msg", e.getMessage());
        } finally {
            if (CollectionUtils.isEmpty(resultMap)) {
                resultMap.put("msg", "我不知道你干了什么");
            }
        }
        return resultMap;

    }

    /**
     * 多线程读取文件
     *
     * @param filePath
     */
    public static void threadRandomAccessFile(String filePath, ThreadPoolExecutor threadPoolExecutor) {
        try (RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "rw")) {
            // 获取线程个数
            int poolSize = threadPoolExecutor.getCorePoolSize();
            // 获取文件大小
            long length = randomAccessFile.length();
            // 计算每条线程的开始位置
            int startSize = Math.toIntExact(length % poolSize + 1);
            int[] starQos = new int[startSize];
            for (int i = 0; i < startSize; i++) {
                starQos[i] = i * startSize;
            }
            System.out.println();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String recursionReadFile(File file) {
        if (file.getPath().contains("template") || file.getPath().contains("slhz.sql")) {
            return "";
        }
        StringBuilder resultStr = new StringBuilder();
        if (file.exists()) {
            if (file.isFile()) {
                try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
                    resultStr.append("\n");
                    resultStr.append("/*************************/\n");
                    resultStr.append(file.getName()).append("\n");
                    resultStr.append("/*************************/\n");
                    String readLine = reader.readLine();
                    while (readLine != null) {
                        readLine = readLine.replace("zhangfusheng", "slhz");
                        resultStr.append(readLine).append("\n");
                        readLine = reader.readLine();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                File[] files = file.listFiles();
                assert files != null;
                for (File f : files) {
                    resultStr.append(recursionReadFile(f));
                }
            }
        }
        return resultStr.toString();
    }

    public static void writFile(String filePath, String fileContent) {
        File file = new File(filePath);
        try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file))){
            if (!file.exists()) {
                boolean newFile = file.createNewFile();
                if (!newFile) {
                    throw new Exception("创建文件失败");
                }
            }
            //BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
            bufferedWriter.write(fileContent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
